<template>
  <div ref="dynamicChart" style="width: 1000px; height: 500px"></div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';
import { useAuthenticationStore } from '@/store/Authentication/Authentication';
import useDataFormatter from '@/hooks/useDataFormatter';
import wsUrl from '@/utilities/wsUrlTool';

const emit = defineEmits(['send-chart-box']);

const authenticationStore = useAuthenticationStore();

const dynamicChart = ref();

const { unitFormatter } = useDataFormatter();
const props = defineProps<{
  sensorsName: string;
  type: string;
  memberId: string;
  units: string;
  lowerCaution: number;
  upperCaution: number;
  lowerCritical: number;
  upperCritical: number;
  currentValue: number;
}>();

let chart = {} as echarts.ECharts;
const option = ref({} as any);
const currentTime = ref(0);
const currentDataArray = ref([props.currentValue, 1, 0] as number[]);
const webSocket = ref(null as null | WebSocket);

const setupChart = () => {
  let lowerCritical = props.lowerCritical ? props.lowerCritical : 0;
  let upperCritical = props.upperCritical ? props.upperCritical : 0;
  let lowerCaution = props.lowerCaution ? props.lowerCaution : 0;
  let upperCaution = props.upperCaution ? props.upperCaution : 0;
  let currentValue = props.currentValue ? props.currentValue : 0;
  let ymax = Math.ceil(
    Math.max(
      currentValue,
      lowerCritical,
      upperCritical,
      lowerCaution,
      upperCaution,
    ) * 1.1,
  );
  let ymin = Math.floor(
    Math.min(
      currentValue,
      lowerCritical,
      upperCritical,
      lowerCaution,
      upperCaution,
    ) * 0.9,
  );
  option.value = {
    legend: {
      data: [props.sensorsName],
      right: 10,
      top: 10,
    },
    tooltip: {
      trigger: 'axis',
    },
    xAxis: {
      type: 'category',
      data: [],
    },
    yAxis: {
      type: 'value',
      name: 'units(' + unitFormatter(props.units) + ')',
      max: ymax,
      min: ymin,
    },
    series: [
      {
        name: props.sensorsName,
        type: 'line',
        data: [],
        smooth: true,
        markLine: {
          animation: false,
          data: [
            {
              yAxis: props.lowerCritical ? props.lowerCritical : {},
              lineStyle: {
                color: 'red',
              },
              label: {
                formatter: 'Lower Critical',
              },
            },
            {
              yAxis: props.upperCritical ? props.upperCritical : {},
              lineStyle: {
                color: 'red',
              },
              label: {
                formatter: 'Upper Critical',
              },
            },
            {
              yAxis: props.upperCaution ? props.upperCaution : {},
              lineStyle: {
                color: '#EBEF18',
              },
              label: {
                formatter: 'Upper Caution',
              },
            },
            {
              yAxis: props.lowerCaution ? props.lowerCaution : {},
              lineStyle: {
                color: '#EBEF18',
              },
              label: {
                formatter: 'Lower Caution',
              },
            },
          ],
        },
      },
    ],
  };
  chart.setOption(option.value, true);
};

const linkSocket = () => {
  let ws: WebSocket;
  const data = {
    paths: [
      '/xyz/openbmc_project/sensors/' + props.type + '/' + props.memberId,
    ],
    interfaces: ['xyz.openbmc_project.Sensor.Value'],
  };
  const socketDisabled =
    import.meta.env.VUE_APP_SUBSCRIBE_SOCKET_DISABLED === 'true' ? true : false;
  if (socketDisabled) return;
  const token = authenticationStore.token;
  const wsURL = wsUrl(`wss://${location.host}/subscribe`);

  ws = new WebSocket(wsURL, [token as string]);
  webSocket.value = ws;
  ws.onopen = () => {
    ws.send(JSON.stringify(data));
  };
  ws.onerror = (event) => {
    console.error(event);
  };
  ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (currentDataArray.value[2] === 0) {
      currentDataArray.value[0] = 0;
      currentDataArray.value[1] = 0;
      currentDataArray.value[2] = 1;
    }
    currentDataArray.value += data.properties.Value;
    currentDataArray.value[1]++;
  };
};

const fetchData = () => {
  let currentData = currentDataArray.value[0] / currentDataArray.value[1];
  currentDataArray.value[0] = currentData;
  currentDataArray.value[1] = 1;
  currentDataArray.value[2] = 0;
  option.value.series[0].data.push(currentData);
  currentTime.value += 5;
  option.value.xAxis.data.push(currentTime.value);
  option.value.yAxis.max = Math.max(
    Math.ceil(currentData),
    option.value.yAxis.max,
  );
  option.value.yAxis.min = Math.min(
    Math.floor(currentData),
    option.value.yAxis.min,
  );
  if (option.value.series[0].data.length > 60) {
    option.value.xAxis.data.shift();
    option.value.series[0].data.shift();
  }
  chart.setOption(option.value, true);
};

const sendChartBoxToParent = () => {
  emit('send-chart-box', chart);
};

onMounted(() => {
  chart = echarts.init(dynamicChart.value as HTMLElement);
  setupChart();
  linkSocket();
  setInterval(fetchData, 5000);
  sendChartBoxToParent();
});

onBeforeUnmount(() => {
  webSocket.value!.close();
});
</script>
